package view;

import java.awt.BorderLayout;
import java.awt.Choice;
import java.awt.Color;
import java.awt.Desktop;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;


import recherche.Indexation;
import recherche.LancementAppli;
import recherche.Modele;
import recherche.ModeleBooleen;
import recherche.ModeleVectoriel;
import tools.FrenchStemmer;
import tools.FrenchTokenizer;
import tools.Normalizer;

public class SearchEngine extends JFrame{

	private JButton searchBtn;
	private Choice normChoice;
	private Choice searchMode;
	private JTextField request;
	private JLabel logo;
	private ArrayList<String> wordRequest;
	private SearchEngine view;
	public static String STOP_WORDS = "./stopWords";
	private static JPanel panelResultats = null;
	private static LancementAppli app = new LancementAppli();


	/**
	 * Classe de gestion des événements à la souris pour un JLabel.
	 * @author ejouini
	 *
	 */
	public class MyMouseListener implements MouseListener{

		private String url;
		private JLabel label;

		public MyMouseListener(String url, JLabel lab) {
			this.url = url;
			label = lab;

		}

		/**
		 * Permet d'ouvrir le navigateur avec l'url correspondante au lien lors du click.
		 */
		public void mouseClicked(MouseEvent e) {

			if(Desktop.isDesktopSupported()){		
				if(Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)){
					try {
						try {
							Desktop.getDesktop().browse(new URI(url));
						} catch (IOException e1) {
							// TODO Auto-generated catch block
							e1.printStackTrace();
						}
					} catch (URISyntaxException e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					}
				}
			}

		}

		/**
		 * Bordure mise en noire lors du survol.
		 */
		public void mouseEntered(MouseEvent e) {

			label.setBorder(BorderFactory.createLineBorder(Color.black));
		}

		/**
		 * Bordure remise par défaut lorsqu'on ne survol plus le label.
		 */
		public void mouseExited(MouseEvent e) {
			label.setBorder(null);
		}

		@Override
		public void mousePressed(MouseEvent e) {
			// TODO Auto-generated method stub

		}

		@Override
		public void mouseReleased(MouseEvent e) {
			// TODO Auto-generated method stub

		}

	}

	public SearchEngine(){

		view=this;
		searchBtn = new JButton("Rechercher");
		searchBtn.addActionListener(new ActionButton());
		normChoice = new Choice();
		normChoice.add("Stemmer");
		normChoice.add("Tokenizer");
		searchMode = new Choice();
		searchMode.add("Modèle vectoriel");
		searchMode.add("Modèle booleen");
		request = new JTextField(20);
		request.setForeground(Color.GRAY);
		request.setText("Tapez votre recherche");
		request.setHighlighter(null); 
		request.addMouseListener( new MouseListener()
		{
			@Override
			public void mouseClicked(MouseEvent e) {
				request.setText("");
			}
			@Override
			public void mousePressed(MouseEvent e) {}
			@Override
			public void mouseReleased(MouseEvent e) {}
			@Override
			public void mouseEntered(MouseEvent e) {}
			@Override
			public void mouseExited(MouseEvent e) {}   
		});

		Icon image = new ImageIcon("./data/logo.jpg");
		logo = new JLabel();
		logo.setIcon(image);
		logo.setHorizontalAlignment(SwingConstants.CENTER);

		// Create the menu bar
		JMenuBar menuBar = new JMenuBar();

		// Create a menu
		JMenu menu = new JMenu("Fichier");
		menuBar.add(menu);

		// Create a menu item
		JMenuItem item = new JMenuItem("Relancer indexation");
		item.addActionListener(new ActionMenu ());
		menu.add(item);

		// Install the menu bar in the frame
		this.setJMenuBar(menuBar);


		//logo.setVerticalTextPosition(SwingConstants.NORTH);
		frame();
		this.setBackground (Color.WHITE);
		this.setSize (new Dimension(500,260));
		this.setVisible (true);
		//this.pack ();
		//this.setLayout (new GridLayout(0,1));
		this.setLocation (250, 200);
		this.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
	}

	private void frame(){
		JPanel blockMain = new JPanel(new BorderLayout());
		blockMain.add(logo,BorderLayout.CENTER);
		blockMain.setBackground(Color.WHITE);

		JPanel blockAction = new JPanel();
		blockAction.add(normChoice);
		blockAction.add(searchMode);
		blockAction.add(searchBtn);
		blockAction.setBackground(Color.WHITE);
		blockAction.setSize(new Dimension(500, 50));

		JPanel blockSearch = new JPanel(new BorderLayout());
		blockSearch.add(request,BorderLayout.CENTER);
		blockSearch.add(blockAction, BorderLayout.SOUTH);

		blockMain.add(blockSearch, BorderLayout.SOUTH);
		blockMain.setComponentZOrder(logo, 0);
		//JPanel liste = frameResult(null);
		//liste.setVisible(false);
		this.add(blockMain);
		//this.add(liste);

	}

	private JPanel frameResult(HashMap<String,String> resultat){
		JPanel liste = new JPanel(new FlowLayout());
		for(Map.Entry<String, String> e : resultat.entrySet()){
			JPanel article = new JPanel(new BorderLayout());
			article.add(new JLabel(e.getKey().toString()));
			article.add(new JLabel(e.getValue().toString()));
			liste.add(article);
		}


		return liste;
	}

	public static void main(String [] args){
		new SearchEngine();
	}


	

		public class ActionButton implements ActionListener{

			@Override
			public void actionPerformed(ActionEvent e) {
				SwingUtilities.invokeLater(new Runnable() {
					@Override
					public void run() {


						if (null != panelResultats){
							panelResultats.removeAll();
							view.remove(panelResultats);
							view.setSize(new Dimension(500,260));
							view.validate();
							view.repaint();
						
						}
						wordRequest = new ArrayList<String>();
						String req = request.getText();
						// Si la requete est vide.
											if(req.equals("")){
												JOptionPane.showMessageDialog(null, "Votre requete est vide", "Attention", JOptionPane.WARNING_MESSAGE);
											}
											else {
						if(!req.equals("")) {
							String[] wd = req.split(" ");
							for(int i=0; i<wd.length;i++){
								wordRequest.add(wd[i]);
							}
						}
						Normalizer norm = null;
						try {
							if(normChoice.getSelectedItem().equals("Stemmer")){
								norm = new FrenchStemmer(STOP_WORDS);
								// Fenetre de demande d'indexation
								File indexStemmer = new File("indexStemmer.ser");
								if (!indexStemmer.exists()){
									JFrame f = new JFrame();
									int test = JOptionPane.showConfirmDialog(f, "Attention, l'indexation Stemmer n'a pa encore eu lieu. Voulez-vous indexer maintenant?");
									if (test == JOptionPane.YES_OPTION){
										JFileChooser dialogue = new JFileChooser(new File("."));
										dialogue.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
										File fichier;

										if (dialogue.showOpenDialog(null)== 
												JFileChooser.APPROVE_OPTION) {
											fichier = dialogue.getSelectedFile();

											app.setDirName(fichier.getPath());

											try {
												app.indexationStemmer();
											} catch (IOException e) {
												// TODO Auto-generated catch block
												e.printStackTrace();
											} catch (InterruptedException e) {
												// TODO Auto-generated catch block
												e.printStackTrace();
											}
										}
									}

								}
							}
								else{
									norm = new FrenchTokenizer(STOP_WORDS);
									// Fenetre de demande d'indexation
									File indexTokenizer = new File("indexTokenizer.ser");
									File indexStemmer = new File("indexStemmer.ser");
									if (!indexTokenizer.exists() || !indexStemmer.exists()){
										JFrame f = new JFrame();
										int test = JOptionPane.showConfirmDialog(f, "Attention, l'indexation Tokenizer n'a pa encore eu lieu. Voulez-vous indexer maintenant?");
										if (test == JOptionPane.YES_OPTION){
											JFileChooser dialogue = new JFileChooser(new File("."));
											dialogue.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
											File fichier;

											if (dialogue.showOpenDialog(null)== 
													JFileChooser.APPROVE_OPTION) {
												fichier = dialogue.getSelectedFile();

												app.setDirName(fichier.getPath());

												try {
													app.indexationTokenizer();
												} catch (IOException e) {
													// TODO Auto-generated catch block
													e.printStackTrace();
												} catch (InterruptedException e) {
													// TODO Auto-generated catch block
													e.printStackTrace();
												}
											}
										}

									}

								}
							}
						
						catch (IOException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}


						Modele m = null;
						if(searchMode.getSelectedIndex()==0){
							m = new ModeleVectoriel(wordRequest);
						}
						else{
							m = new ModeleBooleen(wordRequest);
						}



						
						Indexation i = new Indexation();
						


						HashMap<String,String> res; 

						if(normChoice.getSelectedItem().equals("Stemmer") )
							res = app.recherche(wordRequest, m, norm, i.getDfsStemmer(), "indexStemmer.ser");
						else 
							res = app.recherche(wordRequest, m, norm, i.getDfsTokenizer(), "indexTokenizer.ser");




						panelResultats = new JPanel(new GridLayout());
						
						
						JPanel pan = new JPanel(new GridLayout(res.size(),1));
						String titre;
						JLabel ligne;

						panelResultats.setPreferredSize(new Dimension(640,200));

						JScrollPane scrollPane = 
								new JScrollPane(pan,
										JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
										JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);			

						// Si nous n'avons aucun resultats
						if (0 == res.size()) {
							ligne = (new JLabel("   " + "Aucun résultats."));
							pan.add(ligne);
						}
						else {
							// Pour chaque résultat nous l'insérons dans un label qui est ensuite
							// integré au panel.
							for(Map.Entry<String, String> e : res.entrySet()){

								// On met la premiere lettre du titre en majuscule
								titre = e.getValue().toString();
								titre = " > " + titre.replaceFirst (".", (titre.charAt(0) + "").toUpperCase());

								// On fixe une largeur limite à la ligne en terme de caracteres
								if (titre.length() > 85) 
									ligne = (new JLabel(titre.substring(0, 85)));
								else
									ligne = (new JLabel(titre));

								// MouseListener pour surligner la ligne lors du survol et ouvrir
								// le navigateur lors du click sur la ligne avec l'url correspondant.
								ligne.addMouseListener(new MyMouseListener(e.getKey(), ligne) );

								// Ajout de la description lors du survol de la souris
								ligne.setToolTipText(e.getKey());

								// Ajout du label au jpanel
								pan.add(ligne);

							}
						}

						panelResultats.add(scrollPane);			
						view.add(panelResultats, BorderLayout.SOUTH);
						view.setSize(new Dimension(640,450));
						view.validate();
						view.repaint();
						//view.pack();
					}
					}
				});



			}


			}

		
		public class ActionMenu implements ActionListener{

			@Override
			public void actionPerformed(ActionEvent e) {
				SwingUtilities.invokeLater(new Runnable() {
					@Override
					public void run() {
						
						
						Normalizer norm = null;
						try {
							if(normChoice.getSelectedItem().equals("Stemmer")){
								norm = new FrenchStemmer(STOP_WORDS);
								// Fenetre de demande d'indexation
								File indexStemmer = new File("indexStemmer.ser");
								
									
										JFileChooser dialogue = new JFileChooser(new File("."));
										dialogue.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
										File fichier;

										if (dialogue.showOpenDialog(null)== 
												JFileChooser.APPROVE_OPTION) {
											fichier = dialogue.getSelectedFile();

											app.setDirName(fichier.getPath());

											try {
												app.indexationStemmer();
											} catch (IOException e) {
												// TODO Auto-generated catch block
												e.printStackTrace();
											} catch (InterruptedException e) {
												// TODO Auto-generated catch block
												e.printStackTrace();
											}
										}
									

								}

								else{
									norm = new FrenchTokenizer(STOP_WORDS);
									// Fenetre de demande d'indexation
									File indexTokenizer = new File("indexTokenizer.ser");
									
										
											JFileChooser dialogue = new JFileChooser(new File("."));
											dialogue.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
											File fichier;

											if (dialogue.showOpenDialog(null)== 
													JFileChooser.APPROVE_OPTION) {
												fichier = dialogue.getSelectedFile();

												app.setDirName(fichier.getPath());

												try {
													app.indexationTokenizer();
												} catch (IOException e) {
													// TODO Auto-generated catch block
													e.printStackTrace();
												} catch (InterruptedException e) {
													// TODO Auto-generated catch block
													e.printStackTrace();
												}
											}
										

									

								}
							
						}
						catch (IOException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}

					}
				});
			
		
		}}}
	

